package com.jas.storage;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.jas.common.Action;
import com.jas.common.CommandFormatException;
import com.jas.common.Event;
import com.jas.common.Language;
import com.jas.common.Notification;
import com.jas.common.Utilities;

public class StorageAPI {
	private static final String gatewayFileName = Utilities
			.getDefaultGatewayFileName();
	private static final String notificationFileName = Utilities
			.getDefaultNotificationFileName();
	
	//@author a0118677r
	public static void storeEventList(List<Event> listOfEventsToBeStored) throws StorageException{
		GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder.setPrettyPrinting();
		gsonBuilder.registerTypeAdapter(listOfEventsToBeStored.getClass(), new EventSerializer());
		Gson gson = gsonBuilder.create();
		
		String outputString = gson.toJson(listOfEventsToBeStored);
		
		try{
			File file = new File(Utilities.getDefaultFileName());
			
			if(!file.exists()){
				
				file.createNewFile();
			}
			
			FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
			BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
			bufferedWriter.write(outputString);
			bufferedWriter.close();
			fileWriter.close();
		} catch(IOException e){
			throw new StorageException(Language.getString("ERROR_COULD_NOT_STORE"));
		}
	}
	
	//@author a0118677r
	@SuppressWarnings("unchecked")
	public static List<Event> loadEventList() throws StorageException{
		ArrayList<Event> listOfEvents = new ArrayList<Event>();
		try{
			Gson gson = new GsonBuilder().registerTypeAdapter(listOfEvents.getClass(), new EventDeserializer()).create();
			
			File file = new File(Utilities.getDefaultFileName());
			
			if(!file.exists()){
				return listOfEvents;
			}
			
			FileReader fileReader = new FileReader(file);
			BufferedReader bufferedReader = new BufferedReader(fileReader);
			
			listOfEvents = gson.fromJson(bufferedReader, listOfEvents.getClass());
			
			return listOfEvents;
		} catch(IOException e){
			throw new StorageException(Language.getString("ERROR_COULD_NOT_LOAD_FILE"));
		}
	}
	
	//@author A0121310J
	public void storeActionList(ArrayList<Action> actionList){
		ActionList.setActionList(actionList);
	}
	
	// @author A0098803W
		private ArrayList<String> extractNotifyCommandFromUser(String sentence) {
			sentence.trim();
			ArrayList<String> userCommand = new ArrayList<String>();
			if (sentence.startsWith("@")) {
				try {
					String[] splittedParameters = sentence.split(" ");
					String date = splittedParameters[0].trim();
					if (date.length() == 1) {
						throw new CommandFormatException(
								Language.getString("ERROR_UNRECOGNISED_COMMAND"));
					}
					date = date.substring(1, date.length());
					String msg = "";

					String dateFormat = Utilities.getDateFormat(date);
					if (dateFormat.isEmpty()) {
						throw new CommandFormatException(
								Language.getString("ERROR_WRONG_DATE_FORMAT"));
					} else {

						for (int i = 1; i < splittedParameters.length; i++) {
							msg += splittedParameters[i] + " ";
						}
						userCommand.add(0, date);
						userCommand.add(1, dateFormat);
						userCommand.add(2, msg);

					}

				
					return userCommand;
				} catch (ArrayIndexOutOfBoundsException | CommandFormatException e) {
					System.out.println(e.getMessage());
					return userCommand;
				}
			}
			return userCommand;

		}
		
		// @author A0098803W
		/**
		 * This method stores the message gateway settings in a a human readable
		 * format.
		 * 
		 * @param url
		 *            The message gateway URL.
		 * @throws StorageException
		 */
		public static void storeGatewaySettings(String url) throws StorageException {

			GsonBuilder gsonBuilder = new GsonBuilder();
			gsonBuilder.setPrettyPrinting();

			Gson gson = gsonBuilder.create();

			String outputString = gson.toJson(url);

			try {

				File file = new File(gatewayFileName);

				if (!file.exists()) {

					file.createNewFile();
				}

				FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
				BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
				bufferedWriter.write(outputString);
				bufferedWriter.close();
				fileWriter.close();
			} catch (IOException e) {
				throw new StorageException(
						Language.getString("ERROR_COULD_NOT_STORE"));
			}

		}

		// @author A0098803W
		/**
		 * Gets the default message gateway URL.
		 * 
		 * @return Returns the default message gateway URL.
		 * @throws StorageException
		 */
		public static String getGatewaySettings() throws StorageException {

			String gatewayUrl = "";
			try {
				Gson gson = new GsonBuilder().create();

				File file = new File(gatewayFileName);

				if (!file.exists()) {
					return gatewayUrl;
				}

				FileReader fileReader = new FileReader(file);
				BufferedReader bufferedReader = new BufferedReader(fileReader);

				gatewayUrl = gson.fromJson(bufferedReader, String.class);

				return gatewayUrl;
			} catch (IOException e) {
				throw new StorageException(
						Language.getString("ERROR_COULD_NOT_LOAD_FILE"));
			}

		}

		// @author A0098803W
		/**
		 * 
		 * This method stores the notification list in a a human readable format.
		 * 
		 * @param listOfNotificationToBeStored
		 *            The list of <code>Notification</code> items to store.
		 * @throws StorageException
		 */
		public static void storeNotificationList(
				List<Notification> listOfNotificationToBeStored)
				throws StorageException {

			GsonBuilder gsonBuilder = new GsonBuilder();
			gsonBuilder.setPrettyPrinting();
			Gson gson = gsonBuilder.create();

			String outputString = gson.toJson(listOfNotificationToBeStored);

			try {
				File file = new File(notificationFileName);

				if (!file.exists()) {

					file.createNewFile();
				}

				FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
				BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
				bufferedWriter.write(outputString);
				bufferedWriter.close();
				fileWriter.close();
			} catch (IOException e) {
				throw new StorageException(
						Language.getString("ERROR_COULD_NOT_STORE"));
			}
		}

		// @author A0098803W
		/**
		 * 
		 * This method returns the notifications currently stored by the program.
		 * 
		 * @return The notification list
		 * @throws StorageException
		 */
		@SuppressWarnings("unchecked")
		public static List<Notification> loadNotificationList() throws StorageException {
			ArrayList<Notification> listOfNotificationEvents = new ArrayList<Notification>();
			try {
				Gson gson = new GsonBuilder().create();

				File file = new File(notificationFileName);

				if (!file.exists()) {
					return listOfNotificationEvents;
				}

				FileReader fileReader = new FileReader(file);
				BufferedReader bufferedReader = new BufferedReader(fileReader);
				Type type = new TypeToken<List<Notification>>(){}.getType();
				listOfNotificationEvents = gson.fromJson(bufferedReader,
						type);

				return listOfNotificationEvents;
			} catch (IOException e) {
				throw new StorageException(
						Language.getString("ERROR_COULD_NOT_LOAD_FILE"));
			}
		}
	}

	

